package yt.demo.appcoresystem.aspect;

import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import yt.demo.appcommonbean.http.Request;
import yt.demo.appcommontools.utils.Ip2RegionUtils;
import yt.demo.appcommontools.utils.RequestUtils;
import yt.demo.appcorebasic.annotation.LogOperation;
import yt.demo.appcoresystem.entity.SystemOperLog;
import yt.demo.appcoresystem.entity.SystemUser;
import yt.demo.appcoresystem.impl.AuthService;
import yt.demo.appcoresystem.service.ISystemOperLogService;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class LogOperationAspect {


    @Autowired
    private ISystemOperLogService operLogService;

    @Pointcut("@annotation(yt.demo.appcorebasic.annotation.LogOperation)")
    public void operationPointcut() {
    }

    // 后置通知，记录操作日志
    @AfterReturning(value = "operationPointcut()", returning = "result")
    public void afterOperation(JoinPoint joinPoint, Object result) {

        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取目标方法的 LogOperation 注解
        LogOperation logOperation = signature.getMethod().getAnnotation(LogOperation.class);

        SystemUser userInfo = AuthService.getUserInfo();

        HttpServletRequest request = RequestUtils.getRequestAttributes().getRequest();
        HttpServletResponse response = RequestUtils.getRequestAttributes().getResponse();

        String ip = Request.getClientIp(request);

        // 获取方法参数（如果有的话）
        Object[] args = joinPoint.getArgs();
        Map<String, String> Headers = RequestUtils.getAllRequestHeaders(request);
        
        SystemOperLog data = new SystemOperLog();
        data.setUsername(userInfo.getUsername());
        data.setIp(ip);
        data.setIpLocation(Ip2RegionUtils.getIpAddress(ip));
        data.setMethod(request.getMethod());
        data.setRouter(request.getRequestURI());
        data.setServiceName(logOperation.description());
        data.setRequestBody(JSONUtil.toJsonStr(args));
        data.setRequestHeaders(JSONUtil.toJsonStr(Headers));
        if (response != null) {
            data.setResponseCode(response.getStatus());
        }
        if (response != null) {
            data.setResponseHeaders(JSONUtil.toJsonStr(RequestUtils.getAllResponseHeaders(response)));
        }
        data.setResponseBody(JSONUtil.toJsonStr(result));
        operLogService.create(data);
    }


}
